package com.derbysoft.dswitch.adapter.ihg.common.repository.impl;

import com.derbysoft.dswitch.adapter.ihg.common.domain.OperationType;
import com.derbysoft.dswitch.adapter.ihg.common.domain.RequestCode;
import com.derbysoft.dswitch.adapter.ihg.common.domain.ReservationLog;
import com.derbysoft.dswitch.adapter.ihg.common.domain.ResponseStatus;
import com.derbysoft.dswitch.adapter.ihg.common.repository.ReservationLogService;
import com.derbysoft.dswitch.adapter.ihg.common.utils.DateTimeUtils;
import com.derbysoft.dswitch.adapter.ihg.web.action.admin.requestlog.DMXQueryCondition;
import com.derbysoft.dswitch.adapter.ihg.web.action.admin.requestlog.RequestLogCondition;
import com.derbysoft.dswitch.adapter.ihg.web.action.support.Paginater;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by: jason
 * Date: 2012-06-04
 */
@Service("reservationLogService")
public class ReservationLogServiceImpl
        extends CommonService<ReservationLog> implements ReservationLogService {
    private static final String TIME_SPAN = "timeSpan";
    private static final String OPERATION_TYPE = "operationType";
    private static final String TIMESTAMP = "timestamp";

    @Override
    public List<ReservationLog> loadByErsp(String ersp) {
        DetachedCriteria criteria = DetachedCriteria.forClass(ReservationLog.class).addOrder(Order.desc(TIMESTAMP));
        criteria.add(Restrictions.eq("ersp", ersp));
        return find(criteria);
    }

    @Override
    public void paginater(DMXQueryCondition condition, Paginater paginater) {
        DetachedCriteria criteria = DetachedCriteria.forClass(ReservationLog.class).addOrder(Order.desc(TIMESTAMP));
        if (condition == null) {
            super.paginater(criteria, paginater);
            return;
        }
        if (condition.getRequestCode() == RequestCode.OTA_HotelPreviewRQ) {
            eq(criteria, OPERATION_TYPE, OperationType.HOTEL_PREVIEW);
        }
        if (condition.getRequestCode() == RequestCode.OTA_HotelResRQ) {
            eq(criteria, OPERATION_TYPE, OperationType.HOTEL_RESERVATION);
        }
        if (condition.getRequestCode() == RequestCode.OTA_CancelRQ) {
            eq(criteria, OPERATION_TYPE, OperationType.CANCEL_RESERVATION);
        }
        if (condition.getResponseStatus() != null) {
            eq(criteria, "error", condition.getResponseStatus() == ResponseStatus.ERROR);
        }
        if (StringUtils.isNotBlank(condition.getTaskId())) {
            eq(criteria, "taskId", condition.getTaskId());
        }
        if (StringUtils.isNotBlank(condition.getChannelCode())) {
            eq(criteria, "channel", condition.getChannelCode());
        }
        if (StringUtils.isNotBlank(condition.getHotelCode())) {
            ilike(criteria, "hotels", condition.getHotelCode());
        }

        if (StringUtils.isNotBlank(condition.getErspNo())) {
            eq(criteria, "ersp", condition.getErspNo());
        }
        if (condition.getMinSpentTime() != null) {
            criteria.add(Restrictions.ge(TIME_SPAN, condition.getMinSpentTime()));
        }
        if (condition.getMaxSpentTime() != null) {
            criteria.add(Restrictions.le(TIME_SPAN, condition.getMaxSpentTime()));
        }
        if (StringUtils.isNotBlank(condition.getStartDate())) {
            criteria.add(Restrictions.ge(TIMESTAMP, DateTimeUtils.parse(condition.getStartDate())));
        }
        if (StringUtils.isNotBlank(condition.getEndDate())) {
            criteria.add(Restrictions.lt(TIMESTAMP, DateTimeUtils.addDays(DateTimeUtils.parse(condition.getEndDate()), 1)));
        }
        paginater(criteria, paginater);
    }

    @Override
    public Paginater paginater(RequestLogCondition condition, Paginater paginater) {
        DetachedCriteria criteria = DetachedCriteria.forClass(ReservationLog.class).addOrder(Order.desc(TIMESTAMP));
        if (condition == null) {
            return super.paginater(criteria, paginater);
        }
        if (condition.getResponseStatus() != null) {
            eq(criteria, "error", condition.getResponseStatus() == ResponseStatus.ERROR);
        }
        if (StringUtils.isNotBlank(condition.getTaskId())) {
            eq(criteria, "taskId", condition.getTaskId());
        }
        if (StringUtils.isNotBlank(condition.getHotelCode())) {
            eq(criteria, "hotels", condition.getHotelCode());
        }

        if (StringUtils.isNotBlank(condition.getErspNo())) {
            eq(criteria, "ersp", condition.getErspNo());
        }
        if (condition.getMinSpentTime() != null) {
            criteria.add(Restrictions.ge(TIME_SPAN, condition.getMinSpentTime()));
        }
        if (condition.getMaxSpentTime() != null) {
            criteria.add(Restrictions.le(TIME_SPAN, condition.getMaxSpentTime()));
        }
        if (StringUtils.isNotBlank(condition.getDate())) {
            criteria.add(Restrictions.ge(TIMESTAMP, DateTimeUtils.parse(condition.getDate())));
            criteria.add(Restrictions.lt(TIMESTAMP, DateTimeUtils.addDays(DateTimeUtils.parse(condition.getDate()), 1)));
        }

        return paginater(criteria, paginater);
    }
}
